package com.wlyuan.open.infrastructure.repository;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.wlyuan.mybatis.query.PageUtils;
import com.wlyuan.mybatis.query.QueryUtils;
import com.wlyuan.mybatis.utils.RepositoryUtils;
import com.wlyuan.open.dao.entity.OpenApiInfoDO;
import com.wlyuan.open.dao.mapper.OpenApiInfoMapper;
import com.wlyuan.open.domain.api.OpenApiInfo;
import com.wlyuan.open.domain.api.respository.OpenApiInfoRepository;
import com.wlyuan.open.domain.api.valueobj.OpenApiId;
import com.wlyuan.open.domain.api.valueobj.OpenApiInfoId;
import com.wlyuan.open.domain.client.OpenClientId;
import com.wlyuan.open.dto.api.OpenApiCompanyFilterDTO;
import com.wlyuan.open.infrastructure.config.OpenApiCompanyProperties;
import com.wlyuan.open.infrastructure.converter.OpenApiInfoConverter;
import com.wlyuan.utils.Page;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import lombok.var;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import javax.validation.constraints.NotNull;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.stream.Collectors;

/**
 * @author yuanzheng
 */
@Service
@RequiredArgsConstructor
@Slf4j
public class OpenApiInfoRepositoryImpl implements OpenApiInfoRepository {
    private final OpenApiInfoMapper openApiInfoMapper;
    private final OpenApiCompanyProperties openApiCompanyProperties;

    @Override
    public OpenApiInfo ofId(@NotNull OpenApiInfoId openApiInfoId) {
        return OpenApiInfoConverter.convert(openApiInfoMapper.selectById(openApiInfoId.getId()));
    }

    @Override
    public OpenApiInfoId save(OpenApiInfo openApiInfo) {
        var apiInfoDO = RepositoryUtils.save(openApiInfoMapper,
                OpenApiInfoConverter::convert,
                openApiInfo, openApiInfo.getId());

        openApiInfo.setId(new OpenApiInfoId(apiInfoDO.getId()));
        return openApiInfo.getId();
    }

    @Override
    public void remove(OpenApiInfoId openApiInfoId) {
        openApiInfoMapper.deleteById(openApiInfoId.getId());
    }

    @Override
    public List<OpenApiInfo> list(Collection<OpenApiInfoId> openApiInfoIds) {
        if (CollectionUtils.isEmpty(openApiInfoIds)) {
            return Collections.emptyList();
        }
        List<Long> ids = openApiInfoIds.stream().map(OpenApiInfoId::getId).collect(Collectors.toList());
        LambdaQueryWrapper<OpenApiInfoDO> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.in(OpenApiInfoDO::getId, ids).orderByDesc(OpenApiInfoDO::getId);
        return OpenApiInfoConverter.convert(openApiInfoMapper.selectList(queryWrapper));
    }

    @Override
    public Page<OpenApiInfoId> search(OpenApiCompanyFilterDTO filter) {
        QueryWrapper<OpenApiInfoDO> query = QueryUtils.build(openApiCompanyProperties.getSearch().getRules(), filter);
        var result = openApiInfoMapper.selectPage(PageUtils.page(filter), query);
        return PageUtils.as(result, openApiCompany -> new OpenApiInfoId(openApiCompany.getId()));
    }

    @Override
    public OpenApiInfo getByClientIdAndApiId(OpenClientId openClientId, OpenApiId openApiId) {
        LambdaQueryWrapper<OpenApiInfoDO> query = new LambdaQueryWrapper<>();
        query.eq(OpenApiInfoDO::getClientId, openClientId.getId()).eq(OpenApiInfoDO::getApiId, openApiId.getId());
        return OpenApiInfoConverter.convert(openApiInfoMapper.selectOne(query));
    }

    @Override
    public List<OpenApiInfo> getByClientId(OpenClientId clientId) {
        LambdaQueryWrapper<OpenApiInfoDO> query = new LambdaQueryWrapper<>();
        query.eq(OpenApiInfoDO::getClientId, clientId.getId());
        return OpenApiInfoConverter.convert(openApiInfoMapper.selectList(query));
    }

    @Override
    public void removeByClient(OpenClientId openClientId) {
        LambdaQueryWrapper<OpenApiInfoDO> query = new LambdaQueryWrapper<>();
        query.eq(OpenApiInfoDO::getClientId, openClientId.getId());
        openApiInfoMapper.delete(query);
    }
}
